using DocumentCreationSystem.Models;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System.IO;

namespace DocumentCreationSystem.Services;

/// <summary>
/// 项目历史记录服务实现
/// </summary>
public class ProjectHistoryService : IProjectHistoryService
{
    private readonly ILogger<ProjectHistoryService> _logger;
    private readonly string _historyFilePath;
    private List<ProjectHistory> _histories;
    private readonly object _lockObject = new object();

    public ProjectHistoryService(ILogger<ProjectHistoryService> logger)
    {
        _logger = logger;

        // 历史记录文件存储在应用数据目录
        var dataDirectory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "DocumentCreationSystem");
        Directory.CreateDirectory(dataDirectory);
        _historyFilePath = Path.Combine(dataDirectory, "project_history.json");

        _histories = new List<ProjectHistory>();
        // 不在构造函数中调用异步方法，改为同步加载或延迟加载
        LoadHistorySync();
    }

    private void LoadHistorySync()
    {
        try
        {
            if (File.Exists(_historyFilePath))
            {
                var json = File.ReadAllText(_historyFilePath);
                if (!string.IsNullOrWhiteSpace(json))
                {
                    var histories = JsonConvert.DeserializeObject<List<ProjectHistory>>(json);
                    if (histories != null)
                    {
                        _histories = histories;
                        _logger.LogInformation($"加载了 {_histories.Count} 条历史记录");
                    }
                }
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "加载历史记录失败");
            _histories = new List<ProjectHistory>();
        }
    }

    public async Task AddOrUpdateHistoryAsync(string projectPath, string projectName, string projectType = "Normal")
    {
        try
        {
            if (string.IsNullOrWhiteSpace(projectPath) || string.IsNullOrWhiteSpace(projectName))
            {
                _logger.LogWarning("项目路径或名称为空，无法添加历史记录");
                return;
            }

            // 标准化路径
            var normalizedPath = Path.GetFullPath(projectPath).TrimEnd(Path.DirectorySeparatorChar);

            lock (_lockObject)
            {
                // 查找现有记录（按路径查找）
                var existingHistory = _histories.FirstOrDefault(h =>
                    Path.GetFullPath(h.RootPath).TrimEnd(Path.DirectorySeparatorChar)
                        .Equals(normalizedPath, StringComparison.OrdinalIgnoreCase));

                if (existingHistory != null)
                {
                    // 更新现有记录
                    existingHistory.Name = projectName;
                    existingHistory.Type = projectType;
                    existingHistory.LastAccessTime = DateTime.Now;
                    existingHistory.AccessCount++;
                    _logger.LogInformation($"更新项目历史记录: {projectName}，访问次数: {existingHistory.AccessCount}");
                }
                else
                {
                    // 检查是否存在相同名称的项目（防止重复名称）
                    var duplicateNameHistory = _histories.FirstOrDefault(h =>
                        h.Name.Equals(projectName, StringComparison.OrdinalIgnoreCase));

                    if (duplicateNameHistory != null)
                    {
                        // 如果存在相同名称但不同路径的项目，为新项目名称添加后缀
                        var counter = 1;
                        var originalName = projectName;
                        while (_histories.Any(h => h.Name.Equals(projectName, StringComparison.OrdinalIgnoreCase)))
                        {
                            projectName = $"{originalName} ({counter})";
                            counter++;
                        }
                        _logger.LogInformation($"检测到重复项目名称，已重命名为: {projectName}");
                    }

                    // 创建新记录
                    var newHistory = new ProjectHistory
                    {
                        Id = _histories.Count > 0 ? _histories.Max(h => h.Id) + 1 : 1,
                        Name = projectName,
                        RootPath = normalizedPath,
                        Type = projectType,
                        LastAccessTime = DateTime.Now,
                        AccessCount = 1,
                        IsFavorite = false
                    };

                    _histories.Add(newHistory);
                    _logger.LogInformation($"添加新项目历史记录: {projectName}");
                }

                // 限制历史记录数量（保留最近50个）
                if (_histories.Count > 50)
                {
                    _histories = _histories
                        .OrderByDescending(h => h.LastAccessTime)
                        .Take(50)
                        .ToList();
                }
            }

            await SaveHistoryAsync();
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"添加或更新项目历史记录失败: {projectName}");
        }
    }

    public async Task<List<ProjectHistory>> GetAllHistoryAsync()
    {
        await Task.CompletedTask;
        lock (_lockObject)
        {
            return _histories
                .Where(h => IsProjectPathValid(h.RootPath))
                .OrderByDescending(h => h.LastAccessTime)
                .ToList();
        }
    }

    public async Task<List<ProjectHistory>> GetRecentHistoryAsync(int count = 10)
    {
        await Task.CompletedTask;
        lock (_lockObject)
        {
            return _histories
                .Where(h => IsProjectPathValid(h.RootPath))
                .OrderByDescending(h => h.LastAccessTime)
                .Take(count)
                .ToList();
        }
    }

    public async Task<List<ProjectHistory>> GetFavoriteHistoryAsync()
    {
        await Task.CompletedTask;
        lock (_lockObject)
        {
            return _histories
                .Where(h => h.IsFavorite && IsProjectPathValid(h.RootPath))
                .OrderByDescending(h => h.LastAccessTime)
                .ToList();
        }
    }

    public async Task SetFavoriteAsync(string projectPath, bool isFavorite)
    {
        try
        {
            var normalizedPath = Path.GetFullPath(projectPath).TrimEnd(Path.DirectorySeparatorChar);

            lock (_lockObject)
            {
                var history = _histories.FirstOrDefault(h => 
                    Path.GetFullPath(h.RootPath).TrimEnd(Path.DirectorySeparatorChar)
                        .Equals(normalizedPath, StringComparison.OrdinalIgnoreCase));

                if (history != null)
                {
                    history.IsFavorite = isFavorite;
                    _logger.LogInformation($"设置项目收藏状态: {history.Name} -> {isFavorite}");
                }
            }

            await SaveHistoryAsync();
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"设置项目收藏状态失败: {projectPath}");
        }
    }

    public async Task RemoveHistoryAsync(string projectPath)
    {
        try
        {
            var normalizedPath = Path.GetFullPath(projectPath).TrimEnd(Path.DirectorySeparatorChar);

            lock (_lockObject)
            {
                var history = _histories.FirstOrDefault(h => 
                    Path.GetFullPath(h.RootPath).TrimEnd(Path.DirectorySeparatorChar)
                        .Equals(normalizedPath, StringComparison.OrdinalIgnoreCase));

                if (history != null)
                {
                    _histories.Remove(history);
                    _logger.LogInformation($"删除项目历史记录: {history.Name}");
                }
            }

            await SaveHistoryAsync();
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, $"删除项目历史记录失败: {projectPath}");
        }
    }

    public async Task ClearAllHistoryAsync()
    {
        try
        {
            lock (_lockObject)
            {
                _histories.Clear();
            }

            await SaveHistoryAsync();
            _logger.LogInformation("清空所有项目历史记录");
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "清空项目历史记录失败");
        }
    }

    public bool IsProjectPathValid(string projectPath)
    {
        try
        {
            return !string.IsNullOrWhiteSpace(projectPath) && Directory.Exists(projectPath);
        }
        catch
        {
            return false;
        }
    }

    public async Task<int> CleanupInvalidHistoryAsync()
    {
        try
        {
            List<ProjectHistory> invalidHistories;
            lock (_lockObject)
            {
                invalidHistories = _histories
                    .Where(h => !IsProjectPathValid(h.RootPath))
                    .ToList();
            }

            if (invalidHistories.Count > 0)
            {
                lock (_lockObject)
                {
                    foreach (var invalidHistory in invalidHistories)
                    {
                        _histories.Remove(invalidHistory);
                    }
                }

                await SaveHistoryAsync();
                _logger.LogInformation($"清理了 {invalidHistories.Count} 个无效的历史记录");
            }

            return invalidHistories.Count;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "清理无效历史记录失败");
            return 0;
        }
    }

    public async Task<List<ProjectHistory>> GetInvalidHistoryAsync()
    {
        await Task.CompletedTask;
        lock (_lockObject)
        {
            return _histories
                .Where(h => !IsProjectPathValid(h.RootPath))
                .ToList();
        }
    }

    /// <summary>
    /// 清理重复的项目历史记录
    /// </summary>
    public async Task<int> CleanupDuplicateHistoryAsync()
    {
        try
        {
            List<ProjectHistory> duplicatesToRemove = new List<ProjectHistory>();

            lock (_lockObject)
            {
                // 按路径分组，找出重复项
                var groupedByPath = _histories
                    .GroupBy(h => Path.GetFullPath(h.RootPath).TrimEnd(Path.DirectorySeparatorChar).ToLowerInvariant())
                    .Where(g => g.Count() > 1)
                    .ToList();

                foreach (var group in groupedByPath)
                {
                    // 保留最新访问的记录，删除其他重复项
                    var orderedGroup = group.OrderByDescending(h => h.LastAccessTime).ToList();
                    var keepRecord = orderedGroup.First();
                    var duplicates = orderedGroup.Skip(1).ToList();

                    // 合并访问次数
                    keepRecord.AccessCount = orderedGroup.Sum(h => h.AccessCount);

                    // 如果有任何一个是收藏的，保留收藏状态
                    if (orderedGroup.Any(h => h.IsFavorite))
                    {
                        keepRecord.IsFavorite = true;
                    }

                    duplicatesToRemove.AddRange(duplicates);
                    _logger.LogInformation($"发现重复项目记录: {group.Key}，保留最新记录，删除 {duplicates.Count} 个重复项");
                }

                // 移除重复项
                foreach (var duplicate in duplicatesToRemove)
                {
                    _histories.Remove(duplicate);
                }
            }

            if (duplicatesToRemove.Count > 0)
            {
                await SaveHistoryAsync();
                _logger.LogInformation($"清理了 {duplicatesToRemove.Count} 个重复的历史记录");
            }

            return duplicatesToRemove.Count;
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "清理重复历史记录失败");
            return 0;
        }
    }

    /// <summary>
    /// 获取重复的项目历史记录
    /// </summary>
    public async Task<List<ProjectHistory>> GetDuplicateHistoryAsync()
    {
        await Task.CompletedTask;
        lock (_lockObject)
        {
            var duplicates = new List<ProjectHistory>();
            var groupedByPath = _histories
                .GroupBy(h => Path.GetFullPath(h.RootPath).TrimEnd(Path.DirectorySeparatorChar).ToLowerInvariant())
                .Where(g => g.Count() > 1);

            foreach (var group in groupedByPath)
            {
                // 除了最新的记录外，其他都是重复项
                var orderedGroup = group.OrderByDescending(h => h.LastAccessTime).ToList();
                duplicates.AddRange(orderedGroup.Skip(1));
            }

            return duplicates;
        }
    }

    private async Task LoadHistoryAsync()
    {
        try
        {
            if (File.Exists(_historyFilePath))
            {
                var json = await File.ReadAllTextAsync(_historyFilePath);
                var histories = JsonConvert.DeserializeObject<List<ProjectHistory>>(json);
                
                lock (_lockObject)
                {
                    _histories = histories ?? new List<ProjectHistory>();
                }
                
                _logger.LogInformation($"加载项目历史记录: {_histories.Count} 条");
            }
            else
            {
                _logger.LogInformation("项目历史记录文件不存在，创建新的历史记录");
            }
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "加载项目历史记录失败");
            lock (_lockObject)
            {
                _histories = new List<ProjectHistory>();
            }
        }
    }

    private async Task SaveHistoryAsync()
    {
        try
        {
            List<ProjectHistory> historiesToSave;
            lock (_lockObject)
            {
                historiesToSave = new List<ProjectHistory>(_histories);
            }

            var json = JsonConvert.SerializeObject(historiesToSave, Formatting.Indented);
            await File.WriteAllTextAsync(_historyFilePath, json);
            
            _logger.LogDebug($"保存项目历史记录: {historiesToSave.Count} 条");
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "保存项目历史记录失败");
        }
    }
}
